package org.bdware.doip.implementation;

import org.apache.log4j.Logger;
import org.bdware.doip.core.codec.DigitalObjectCodec;
import org.bdware.doip.core.codec.DigitalObjectCodecImpl;
import org.bdware.doip.core.model.digitalObject.DigitalObject;
import org.bdware.doip.core.model.digitalObject.Element;
import org.rocksdb.Options;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;

import java.io.File;

public class DoStorageRocksDBImpl implements DoStorage {

    static Logger logger = Logger.getLogger(DoStorageRocksDBImpl.class);
    RocksDB db;
    String dbPath;
    DigitalObjectCodec doCodec = new DigitalObjectCodecImpl();

    static {
        RocksDB.loadLibrary();
    }

    public DoStorageRocksDBImpl(){
        this("./rocksdb/");
    }

    public DoStorageRocksDBImpl(String dbPath){
        this.dbPath = dbPath;
        Options rockOpts = new Options().setCreateIfMissing(true);
        try {
            logger.debug("rocksdb data path: " + new File(dbPath).getAbsolutePath());
            db = RocksDB.open(rockOpts, dbPath);
        } catch (RocksDBException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    protected RocksDB getDBInstance(){
        return db;
    }

    protected DigitalObjectCodec getDoCodec(){
        return doCodec;
    }

    @Override
    public DigitalObject getDoByID(String id) {
        try {
            return doCodec.ByteArrayToDo(db.get(id.getBytes()));
        }catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    public void storeDo(DigitalObject digitalObject) {
        try {
            db.put(digitalObject.id.getBytes(),doCodec.DoToByteArray(digitalObject));
        }catch (RocksDBException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void deleteDoByID(String id) {
        try {
            db.delete(id.getBytes());
        } catch (RocksDBException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateDo(DigitalObject digitalObject) {
        deleteDoByID(digitalObject.id);
        storeDo(digitalObject);
    }

    @Override
    public Element getElement(String doId, String elementID) {
        DigitalObject digitalObject = getDoByID(doId);
        for(Element e:digitalObject.elements){
            if(e.id.equals(elementID)) return e;
        }
        return null;
    }
}
